﻿using CPPEI.Coolzon.Common;
using CPPEI.Coolzon.Designtime.Metadata;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using DT = CPPEI.Coolzon.Designtime.Metadata;

namespace CPPEI.Coolzon.Designer.Views
{
    public static class UndoThread
    {
        private static bool s_isRunning = false;
        private static Thread s_thread;
        private static Action<Guid, string, int, int> s_progress;
        private static Action<bool, int, int> s_completed;
        private static List<Guid> s_nodeList;

        /// <summary>
        /// solutiontreeviewNode状态在线程中修改
        /// </summary>
        /// <param name="nodeList">需要被撤销的项id</param>
        /// <param name="progress">项目ID, 项目名称，撤销进度，总数量</param>
        /// <param name="completed">是否出现错误，成功数量，总数量</param>
        public static bool Start(List<Guid> itemList, Action<Guid, string, int, int> progress, Action<bool, int, int> completed)
        {
            if (s_isRunning)
            {
                return false;
            }

            s_nodeList = itemList;
            s_progress = progress;
            s_completed = completed;
            s_isRunning = true;
            s_thread = new Thread(Running);
            s_thread.Start();
            return true;
        }

        public static void Stop()
        {
            if (s_isRunning)
            {
                s_thread.Abort();
                s_isRunning = false;
                s_thread = null;
            }
        }

        private static void Running()
        {
            int total = s_nodeList.Count;
            int progress = 0;
            bool hasError = false;

            CPPEI.Coolzon.ServiceProxy.DesignServiceRef.DesignServiceClient dsClient =
                CPPEI.Coolzon.ServiceProxy.DesignServiceProxyManager.Create();

            string workspacePath = UIContext.Current.LocalWorkSpace.LocalPath;
            Guid solutionId = UIContext.Current.CurrentSolution.ID;

            for (int index = 0; index < s_nodeList.Count; index++)
            {
                Guid tvNode = s_nodeList[index];

                VSFile vsFile = VSFileMgr.GetFileWithDefault(workspacePath, solutionId, tvNode);

                if (vsFile.Action == VSFileAction.Add)
                {
                    //删除文件
                    LocalStorage.DeleteFile(workspacePath, solutionId, tvNode);
                    //删除版本记录
                    VSFileMgr.GoToDelete(workspacePath, solutionId, tvNode);
                }
                else
                {
                    try
                    {
                        CPPEI.Coolzon.ServiceProxy.DesignServiceRef.UndoRequest UndoRequest = new ServiceProxy.DesignServiceRef.UndoRequest();
                        UndoRequest.Token = UIContext.Current.Token;
                        UndoRequest.Id = tvNode;
                        UndoRequest.SolutionId = solutionId;
                        CPPEI.Coolzon.ServiceProxy.DesignServiceRef.UndoResponse undoResult = dsClient.Undo(UndoRequest);
                        if (undoResult.IsSuccess)
                        {
                            SaveFile(workspacePath, solutionId, undoResult.ItemId, undoResult.ItemParentId, undoResult.ItemType, undoResult.ItemExtension, undoResult.Content);

                            // 更新本地的文件项目状态
                            VSFileMgr.GoToCheckIn(workspacePath, solutionId, undoResult.ItemId, undoResult.ItemFolderId, undoResult.ItemVersion);
                        }
                        else
                        {
                            Logger.ErrorToTag(Library.LogTAG, string.Format("撤销Id:{0}失败", tvNode));
                            hasError = true;
                            break;
                        }

                        if (tvNode == solutionId)
                        {
                            CPPEI.Coolzon.ServiceProxy.DesignServiceRef.DeleteRequest dRequest = new ServiceProxy.DesignServiceRef.DeleteRequest();
                            dRequest.Token = UIContext.Current.Token;
                            dRequest.Id = tvNode;
                            dRequest.SolutionId = solutionId;
                            dRequest.WorkSpaceId = UIContext.Current.LocalWorkSpace.Id;
                            CPPEI.Coolzon.ServiceProxy.DesignServiceRef.ListResultOf_DeletingList dResult = dsClient.GetDeletingList(dRequest);
                            if (dResult.IsSuccess)
                            {
                                if (dResult.Data != null && dResult.Data.Length > 0)
                                {
                                    foreach (var item in dResult.Data)
                                    {
                                        CPPEI.Coolzon.ServiceProxy.DesignServiceRef.UndoRequest request = new ServiceProxy.DesignServiceRef.UndoRequest();
                                        request.Token = UIContext.Current.Token;
                                        request.Id = item.ItemId;
                                        request.SolutionId = solutionId;
                                        CPPEI.Coolzon.ServiceProxy.DesignServiceRef.UndoResponse result = dsClient.Undo(request);
                                        if (result.IsSuccess)
                                        {
                                            SaveFile(workspacePath, solutionId, result.ItemId, result.ItemParentId, result.ItemType, result.ItemExtension, result.Content);

                                            // 更新本地的文件项目状态
                                            VSFileMgr.GoToCheckIn(workspacePath, solutionId, result.ItemId, result.ItemFolderId, result.ItemVersion);
                                        }
                                        else
                                        {
                                            Logger.ErrorToTag(Library.LogTAG, string.Format("撤销Id:{0}失败", item.ItemId));
                                        }
                                    }
                                }
                            }
                        }

                        progress++;

                        s_progress(tvNode, undoResult.ItemName, progress, total);
                    }
                    catch (Exception ex)
                    {
                        Logger.ErrorToTag(Library.LogTAG, string.Format("撤销Id:{0}失败,ex:{1}", tvNode, ex));
                        hasError = true;
                        break;
                    }
                }
            }
            dsClient.Close();

            s_completed(hasError, progress, total);
            s_isRunning = false;
            s_thread = null;
        }

        private static void SaveFile(string workspacePath, Guid solutionId, Guid itemId, Guid itemParentId, int itemType, string extension, Stream content)
        {
            if (content != null)
            {
                string filePath = string.Empty;

                switch (itemType)
                {
                    case CPPEI.Coolzon.Designer.Views.Models.Constant.ItemType.Solution:
                        // 方案文件
                        filePath = LocalStorage.GetSolutionFileAbsolutePath(workspacePath, solutionId);
                        break;
                    case CPPEI.Coolzon.Designer.Views.Models.Constant.ItemType.Scene:
                        // 场景文件
                        filePath = LocalStorage.GetSceneFileAbsolutePath(workspacePath, solutionId, itemId);
                        break;
                    case CPPEI.Coolzon.Designer.Views.Models.Constant.ItemType.Template:
                        //模板文件
                        filePath = LocalStorage.GetSceneFileAbsolutePath(workspacePath, solutionId, itemParentId);
                        break;
                    case CPPEI.Coolzon.Designer.Views.Models.Constant.ItemType.StaticDataSource:
                        //静态数据源
                        filePath = Designtime.Metadata.LocalStorage.GetStaticDataSourceAbsolutePath(UIContext.Current.LocalWorkSpace.LocalPath, UIContext.Current.CurrentSolution.ID, itemId);
                        break;
                    default:
                        // 资源文件
                        filePath = LocalStorage.GetResourceFileAbsolutePath(workspacePath, solutionId, itemId, extension);
                        break;
                }

                // 保存新的文件
                using (FileStream fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
                {
                    // 我们不用对两个流对象进行读写，只要复制流就OK  
                    content.CopyTo(fileStream);
                    fileStream.Flush();
                }
            }
        }
    }
}
